<?php

use GuzzleHttp\Client;
use Illuminate\Database\Capsule\Manager as DB;

class HelibaoPay
{
    protected $aesKey = 'aidQY44RFA4qUFwi';
    protected $merchantCert = APP_PATH . '/cert/helibao_rsaKey.pfx';
    protected $publicKey = APP_PATH . '/cert/helipay.cer';
    
    public function __construct()
    {

    }

    public function notify($data): string
    {
        Log::out('heliPayNotify-data:' . json_encode($data), 'helipay');
        if(!$this->checkSignature($data)){
            return 'error';
        }
        if (!$data) return 'error';
        if($data['rt2_retCode']!=='0000'){
            return 'error';
        }
        try {
            $data = (object)$data;
            $heiliOrder = helibaoorderModel::query()->where('pay_order_no', $data->rt5_orderId)->first();
            if(!$heiliOrder) return 'error';
            $order = orderModel::query()->where('order_sn', $heiliOrder->order_sn)->first();
            if (!$order) return 'error';
            if ($data->rt9_orderStatus != 'SUCCESS') return 'error';
            if ($order->status > 0) return 'success';

            Db::transaction(function () use ($order, $data) {
                $notify = [
                    'order_sn'       => $order->order_sn,
                    'transaction_id' => $data->rt6_serialNumber,
                    'notify_time'    => $data->rt7_completeDate,
                    'payment_json'   => json_encode($data),
                    'pay_fee'        => $data->rt8_orderAmount,
                    'pay_type'       => "helibao"
                ];
                $order->paymentProcess($order, $notify);
            });
            return 'success';
        } catch (\Exception $e) {
            Log::out('helibaoPayNotify-error:' . $e->getMessage(), 'helipay');
            return 'error';
        }
    }

    public function refund($order, $refund)
    {
        $reqData = [
            'p1_MerchantNo'    => $this->merchantNo,
            'p2_OrderNo'       => $order->order_sn,
            'p3_RefundOrderNo' => $refund->refund_sn,
            'p4_RefundAmount'  => $refund->refund_fee,
            'p6_NotifyUrl'     => $this->notifyUrl,
        ];
        $reqData['hmac'] = $this->signature($reqData);
        $response = (new Client())->post($this->refundUrl, ['form_params' => $reqData]);
        $data = json_decode($response->getBody());
        if ($data->ra_Status === 100) return true;
        return $data->rc_CodeMsg;
    }


    private function checkOpenid($memberId)
    {
        if (!in_array($this->frpCode, ['WEIXIN_GZH', 'WEIXIN_XCX'])) return '';
        $oauth = memberoauthModel::where([
            'member_id'  => $memberId,
            'provider' => 'Wechat',
            'platform' => 'wxOfficialAccount'
        ])->first();
        if ($oauth) return $oauth->openid;
        return false;
    }

    private function checkSignature($data)
    {
        $params = [
            'rt1_bizType' 			=> $data['rt1_bizType'],
            'rt2_retCode' 			=> $data['rt2_retCode'],
            'rt3_retMsg' 			=> $data['rt3_retMsg'],
            'rt4_customerNumber' 	=> $data['rt4_customerNumber'],
            'rt5_orderId' 			=> $data['rt5_orderId'],
            'rt6_serialNumber' 		=> $data['rt6_serialNumber'],
            'rt7_completeDate' 		=> $data['rt7_completeDate'],
            'rt8_orderAmount' 		=> $data['rt8_orderAmount'],
            'rt9_orderStatus' 		=> $data['rt9_orderStatus'],
            'rt10_bindId' 			=> $data['rt10_bindId'],
            'rt11_bankId' 			=> $data['rt11_bankId'],
            'rt12_onlineCardType' 	=> $data['rt12_onlineCardType'],
            'rt13_cardAfterFour' 	=> $data['rt13_cardAfterFour'],
            'rt14_userId' 			=> $data['rt14_userId'],
        ];
        $signStr  = '&'.implode('&', $params);
        return $this->MD5RSA_verifyOpenssl($signStr, $data['sign']);
    }

    private function MD5RSA_verifyOpenssl(string $data, string $signature){
        if (empty($data)) {
            throw new Exception('data参数不能为空');
        }
        $rsa_public = file_get_contents($this->publicKey);
        $rsa_key    = openssl_pkey_get_public($rsa_public);
        if (!$rsa_key) {
            throw new Exception('公钥不可用');
        }
        $signature=base64_decode($signature);

        return openssl_verify($data, $signature, $rsa_key, OPENSSL_ALGO_MD5);
    }

}